package org.example.netty.test.nio.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.Scanner;
import java.util.concurrent.TimeUnit;

/**
 * @author zp
 * @version 1.0
 * @description: 使用异步非阻塞的方式 断开连接
 * ChannelFuture
 * isDone()	任务是否执行完成，无论成功还是失败
 * isSuccess()	任务是否执行采购
 * isCancelled()	任务是否被取消
 * cause()	获取执行异常信息
 * isDone ()=false、isSuccess ()=false、isCancelled ()=false；
 * 未完成 isDone=false isSuccess=false isCancelled=false
 * 执行完成
 * 成功：isDone=true isSuccess=true
 * 失败：isDone=true isSuccess=false
 * 取消：isDone=true isCancelled=true
 * 只有任务执行 isDone 就会变成true
 *
 * @date 2023/3/9 19:43
 */
@Slf4j
public class ClosFutureClient {
    public static void main(String[] args) {

        NioEventLoopGroup bootstrappedGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap
                    .group(bootstrappedGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                            ch.pipeline().addLast(new StringEncoder());
                        }
                    });
            ChannelFuture syncChannelFuture  = connect(bootstrap,"127.0.0.1", 8888);
            Channel channel = syncChannelFuture.sync().channel();
            new Thread(()->{
                Scanner scanner = new Scanner(System.in);
                while (true){
                    String message = scanner.nextLine();
                    if("quit".equals(message)){
                        log.info("关闭连接");
                        channel.close();
                        break;
                    }
                    channel.writeAndFlush(message);
                }
            },"input").start();

            ChannelFuture channelFuture = channel.closeFuture();
            channelFuture.addListener((ChannelFutureListener) future -> {
                log.info("关闭后的操作");
                bootstrappedGroup.shutdownGracefully();
            });

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    /**
     * @description:   使用异步监听的方式连接 如果未连接 放入默认EventLoop当中 执行递归连接 直到连接成功
     * @author zp
     * @date: 2023/3/14 22:04
     * @param bootstrap
     * @param host
     * @param port
     */
    private static ChannelFuture connect(Bootstrap bootstrap, String host, int port) {
        return bootstrap.connect(host, port).addListener(future -> {
            if (future.isSuccess()) {
                System.out.println("连接成功!");
            } else {
                //获取EventLoopGroup
                EventLoopGroup thread=bootstrap.config().group();
                //每隔5秒钟重连一次
                thread.schedule(() -> connect(bootstrap, host, port), 5, TimeUnit.SECONDS);
            }
        });
    }

}
